From 725756e5d84d45f3fdf744e3cebdaa762e5466dc Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Sun, 14 Jan 2018 18:36:26 +0100 Subject: [PATCH] babl: refactor conversion dispatch to do less branches at runtime --- babl/babl-conversion.c | 111 ++++++++++++++++++++++++++++++++++++ babl/babl-conversion.h | 3 + babl/babl-internal.h | 124 +---------------------------------------- 3 files changed, 115 insertions(+), 123 deletions(-) diff --git a/babl/babl-conversion.c b/babl/babl-conversion.c index 97955e2..78a5f1f 100644 --- a/babl/babl-conversion.c +++ b/babl/babl-conversion.c @@ -34,6 +34,114 @@ static int model_is_rgba (const Babl *model) return 0; } + +static void +babl_conversion_plane_process (BablConversion *conversion, + const void *source, + void *destination, + int src_pitch, + int dst_pitch, + long n, + void *user_data) +{ + conversion->function.plane ((void*)conversion, source, destination, + src_pitch, dst_pitch, + n, + user_data); +} + +static void +babl_conversion_planar_process (const Babl *babl, + const char *src, + char *dst, + long n, + void *user_data) +{ + BablConversion *conversion = (void*)babl; + const BablImage *source = (void*)src; + BablImage *destination = (void*)dst; +#ifdef USE_ALLOCA + const char **src_data = alloca (sizeof (void *) * source->components); + char **dst_data = alloca (sizeof (void *) * destination->components); +#else + const char *src_data[BABL_MAX_COMPONENTS]; + char *dst_data[BABL_MAX_COMPONENTS]; +#endif + + memcpy (src_data, source->data, sizeof (void *) * source->components); + memcpy (dst_data, destination->data, sizeof (void *) * destination->components); + conversion->function.planar ((void*)conversion, + source->components, + src_data, + source->pitch, + destination->components, + dst_data, + destination->pitch, + n, + user_data); +} + +static void dispatch_plane (const Babl *babl, + const char *source, + char *destination, + long n, + void *user_data) +{ + const BablConversion *conversion = &babl->conversion; + const void *src_data = NULL; + void *dst_data = NULL; + int src_pitch = 0; + int dst_pitch = 0; + + if (BABL_IS_BABL (source)) + { + BablImage *img; + + img = (BablImage *) source; + src_data = img->data[0]; + src_pitch = img->pitch[0]; + } + if (BABL_IS_BABL (destination)) + { + BablImage *img = (BablImage *) destination; + + dst_data = img->data[0]; + dst_pitch = img->pitch[0]; + } + + if (!src_data) + src_data = source; + if (!src_pitch) + src_pitch = BABL (conversion->source)->type.bits / 8; + if (!dst_data) + dst_data = destination; + if (!dst_pitch) + dst_pitch = BABL (conversion->destination)->type.bits / 8; + + babl_conversion_plane_process ((void*)conversion, + src_data, dst_data, + src_pitch, dst_pitch, + n, user_data); +} + +static inline void +babl_conversion_rig_dispatch (const Babl *babl) +{ + BablConversion *conversion = (BablConversion *) babl; + switch (BABL (conversion)->class_type) + { + case BABL_CONVERSION_PLANE: + conversion->dispatch = dispatch_plane; + break; + case BABL_CONVERSION_PLANAR: + conversion->dispatch = babl_conversion_planar_process; + break; + case BABL_CONVERSION_LINEAR: + conversion->dispatch = conversion->function.linear; + break; + } +} + Babl * _conversion_new (const char *name, int id, @@ -144,6 +252,7 @@ _conversion_new (const char *name, babl->conversion.error = 0.0; } + babl_conversion_rig_dispatch (babl); return babl; } @@ -432,4 +541,6 @@ const Babl *babl_conversion_get_destination_space (const Babl *conversion) return conversion->conversion.destination->format.space; } + + BABL_CLASS_IMPLEMENT (conversion) diff --git a/babl/babl-conversion.h b/babl/babl-conversion.h index d3fb09a..25bbeea 100644 --- a/babl/babl-conversion.h +++ b/babl/babl-conversion.h @@ -42,6 +42,9 @@ _BablConversion { BablInstance instance; const Babl *source; const Babl *destination; + void (*dispatch) (const Babl *babl, const char *src, char *dst, long n, + void *user_data); + long cost; double error; union diff --git a/babl/babl-internal.h b/babl/babl-internal.h index 3c08ff2..337541b 100644 --- a/babl/babl-internal.h +++ b/babl/babl-internal.h @@ -482,56 +482,6 @@ void babl_space_to_xyz (const Babl *space, const double *rgb, double *xyz); */ void babl_space_from_xyz (const Babl *space, const double *xyz, double *rgb); -static inline void -babl_conversion_linear_process (BablConversion *conversion, - const void *source, - void *destination, - long n) -{ - conversion->function.linear ((void*)conversion, source, destination, n, conversion->data); -} - -static inline void -babl_conversion_plane_process (BablConversion *conversion, - const void *source, - void *destination, - int src_pitch, - int dst_pitch, - long n) -{ - conversion->function.plane ((void*)conversion, source, destination, - src_pitch, dst_pitch, - n, - conversion->data); -} - -static inline void -babl_conversion_planar_process (BablConversion *conversion, - BablImage *source, - BablImage *destination, - long n) -{ -#ifdef USE_ALLOCA - const char **src_data = alloca (sizeof (void *) * source->components); - char **dst_data = alloca (sizeof (void *) * destination->components); -#else - const char *src_data[BABL_MAX_COMPONENTS]; - char *dst_data[BABL_MAX_COMPONENTS]; -#endif - - memcpy (src_data, source->data, sizeof (void *) * source->components); - memcpy (dst_data, destination->data, sizeof (void *) * destination->components); - conversion->function.planar ((void*)conversion, - source->components, - src_data, - source->pitch, - destination->components, - dst_data, - destination->pitch, - n, - conversion->data); -} - static inline void babl_conversion_process (const Babl *babl, @@ -540,81 +490,9 @@ babl_conversion_process (const Babl *babl, long n) { BablConversion *conversion = (BablConversion *) babl; - - // babl_assert (BABL_IS_BABL (conversion)); - - switch (BABL (conversion)->class_type) - { - case BABL_CONVERSION_PLANE: - { - const void *src_data = NULL; - void *dst_data = NULL; - int src_pitch = 0; - int dst_pitch = 0; - - if (BABL_IS_BABL (source)) - { - BablImage *img; - - img = (BablImage *) source; - src_data = img->data[0]; - src_pitch = img->pitch[0]; - } - if (BABL_IS_BABL (destination)) - { - BablImage *img = (BablImage *) destination; - - dst_data = img->data[0]; - dst_pitch = img->pitch[0]; - } - - if (!src_data) - src_data = source; - if (!src_pitch) - src_pitch = BABL (conversion->source)->type.bits / 8; - if (!dst_data) - dst_data = destination; - if (!dst_pitch) - dst_pitch = BABL (conversion->destination)->type.bits / 8; - - babl_conversion_plane_process (conversion, - src_data, dst_data, - src_pitch, dst_pitch, - n); - } - break; - - case BABL_CONVERSION_PLANAR: - babl_assert (BABL_IS_BABL (source)); - babl_assert (BABL_IS_BABL (destination)); - - babl_conversion_planar_process (conversion, - (BablImage *) source, - (BablImage *) destination, - n); - break; - - case BABL_CONVERSION_LINEAR: - /* the assertions relied on a babl_malloc structure - * - * babl_assert (!BABL_IS_BABL (source)); - babl_assert (!BABL_IS_BABL (destination));*/ - - babl_conversion_linear_process (conversion, - source, - destination, - n); - break; - - default: - babl_log ("args=(%s, %p, %p, %li) unhandled conversion type: %s", - conversion->instance.name, source, destination, n, - babl_class_name (conversion->instance.class_type)); - break; - } - conversion->processings++; conversion->pixels += n; + conversion->dispatch (babl, source, destination, n, conversion->data); } #endif -- 2.30.2